// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: qiang

#pragma once

#include <cstdio>
#include <map>
#include <memory>
#include <set>
#include <string>

#include <rapidjson/document.h>

#include "coin2/exchange/apollox/symbology/product.h"
#include "coin2/exchange/apollox_base/api_util/rate_tracker.h"
#include "coin2/exchange/base/order/order.h"

namespace coin2::exchange::apollox::order_v1 {

class ApolloxParser : public base::order::BaseParser {
 public:
  using TransferType = coin::proto::TransferRequestProto::TransferType;

 public:
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& document) override;
  bool ParseRawBalance(const JsonValue& doc, RawBalanceMap* raw_balance_map);

 private:
  void ParseSubmitResponse();
  void ParseCancelResponse();
  void ParseRestOpenOrders();
  void ParseRestAllOrders();
  void ParseRestOrderInfoList();
  void ParseRestFillInfoList();
  void ParseRestSpotAccountBalance();
  void ParseRestMarginCrossedAccountBalance();
  void ParseRestMarginIsolatedAccountBalance();
  void ParseWsMessage();
  void ParseListenKey();
  void ParseRestDeposit();
  void ParseRestWithdrawal();
  void ParseTransfer(bool is_deposit_subaccount);
  ProductOrderBundle ParseWsOrderInfoListV1(const JsonValue& data);
  ProductFillBundle ParseWsFillInfoListV1(const JsonValue& data);
  std::string ParseHeader(const std::shared_ptr<AsioHttpContext>&);
  bool ParseWsBalance(const JsonValue& doc, AccountBalance*);
  ProductOrderElement ParseRestOrderInfo(const JsonValue&);
  bool ParseRawBalanceFromWs(const JsonValue& doc, RawBalanceMap* raw_balance_map);

  void MergeMarginAccountBalance(AccountBalance* acc_balance);

 private:
  bool is_query_historical_orders_{false};
  int64_t last_ws_balance_timestamp_{0};
  bool is_account_balance_initialized_ = false;
  static std::map<std::string, TransferType> transfer_type_map_;
  bool is_crossed_margin_balance_initialized = false;
  bool is_isolated_margin_balance_initialized = false;
  RawBalanceMap crossed_margin_balance_map_cache_;
  RawBalanceMap isolated_margin_balance_map_cache_;
};

}  // namespace coin2::exchange::apollox::order_v1
